package com.huluobo.lib_base

import android.content.Intent
import android.util.Log
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.catch
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.receiveAsFlow
import kotlinx.coroutines.launch
import java.io.File

/**
 *  Created by LC on 2025/3/25.
 */
abstract class BaseViewModel<uiIntent : UIIntent> : ViewModel() {
    //存放管理意图的管道
    private val _uiIntent = Channel<UIIntent> { Channel.UNLIMITED }

    //可变的状态,用于更新UI
    private var _state = MutableStateFlow<UIState>(UIState.OnLoading)
    val state: StateFlow<UIState>
        get() = _state

    init {
        viewModelScope.launch {
            _uiIntent.receiveAsFlow().collect {
                handleIntent(it)
            }
        }
    }

    //所有继承当前BaseViewModel的类,都需要实现该方法,用来处理对应的意图
    //比如登录的Intent,需要处理登录的意图
    abstract fun handleIntent(it: UIIntent)


    //发送意图
    //当页面需要有发起请求获取数据的时候,需要调用该方法,并且传入一个意图
    fun sendIntent(intent: UIIntent) {
        viewModelScope.launch {
            _uiIntent.send(intent)
        }
    }

    //请求方法
    fun httpRequest(request: Flow<Res<Any>>, type: HttpType = HttpType.DEFAULT) {
        viewModelScope.launch {
            request.flowOn(Dispatchers.IO)
                .catch {
                    Log.e("TagA", "网络请求错误:${it.message}")
                }.collect {
                    if (it.code == 0) {
                        //请求成功,把成功的返回值填充给成功的状态中
                        _state.value = UIState.OnSuccess(it.data, type)
                    } else {
                        _state.value = UIState.OnError(it.msg)
                    }
                }
        }
    }

    fun httpRequestVideo(request: Flow<Res2<Any>>, type: HttpType = HttpType.DEFAULT) {
        viewModelScope.launch {
            request.flowOn(Dispatchers.IO)
                .catch {
                    Log.e("TagA", "error:${it.message}")
                }.collect {
                    if (it.code == 200) {
                        _state.value = UIState.OnSuccess(it.data, type)
                    } else {
                        _state.value = UIState.OnError(it.message)
                    }
                }
        }
    }

    //下载的方法
    fun download(url: String, file: File) {
        viewModelScope.launch {
            DownloadUtils.download(url, file)
                .flowOn(Dispatchers.IO)
                .catch {
                    Log.e("TagA", "下载错误:${it.message}")
                }.collect {
                    _state.value = it
                }
        }
    }

    //扫描本地文件的方法
    //参数是文件夹,不是一个文件
    fun scanFile(file: File) {
        viewModelScope.launch {
            try {
                //查找文件夹中所有的文件,形成一个list
                val files = file.listFiles()
                //声明一个集合,集合中包含自己的数据类型,数据类中包含文件名和文件路径
                val list = mutableListOf<LocalEntity>()
                for (i in files) {
                    list.add(LocalEntity(i.name, i.absolutePath))
                }
                _state.value = UIState.OnSuccess(list)

            } catch (e: Exception) {
                _state.value = UIState.OnError(e.message.toString())
            }
        }
    }

    fun roomRequest(request: Flow<Any>, type: HttpType = HttpType.DEFAULT) {
        viewModelScope.launch {
            request.flowOn(Dispatchers.IO)
                .catch {
                    Log.e("TagA", "数据库错误:${it.message}")
                }.collect {
                    if (it != null) {
                        _state.value = UIState.OnSuccess(it, type)
                    } else {
                        _state.value = UIState.OnError("数据库操作错误")
                    }
                }
        }
    }
}